package org.qianji.goosql.dql.clause;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.qianji.goosql.field.Field;

/**
 * 简单查询子句。
 * 
 * @author gmz
 * 
 */
public class SimpleSelect implements Select {

	/**
	 * 
	 */
	private static final long serialVersionUID = -5013860575114764276L;

	protected List<Field> queryFields;
	protected boolean distinct = false;

	/**
	 * 默认构造子。
	 */
	public SimpleSelect() {
		super();
	}

	/**
	 * 根据查询字段构造查询子句。
	 * 
	 * @param queryFields
	 *            {@link List List&lt;Field&gt;} 查询字段
	 */
	public SimpleSelect(List<Field> queryFields) {
		super();
		this.queryFields = queryFields;
	}

	/**
	 * 根据查询字段、是否剔除重复结果构造查询子句。
	 * 
	 * @param queryFields
	 *            {@link List List&lt;Field&gt;} 查询字段
	 * @param distinct
	 *            {@link java.lang.Boolean boolean} true-剔除重复结果，false-不剔除
	 */
	public SimpleSelect(List<Field> queryFields, boolean distinct) {
		super();
		this.queryFields = queryFields;
		this.distinct = distinct;
	}

	@Override
	public List<Field> getQueryFields() {
		return queryFields;
	}

	@Override
	public Select setQueryFields(List<Field> queryFields) {
		this.queryFields = queryFields;
		return this;
	}

	@Override
	public int size() {
		return (queryFields != null ? queryFields.size() : 0);
	}

	@Override
	public Select addQueryField(Field field) {
		if (field == null) {
			throw new NullPointerException("field can't be null");
		}
		if (queryFields == null) {
			queryFields = new ArrayList<Field>();
		}
		if (!queryFields.contains(field)) {
			queryFields.add(field);
		}
		return this;
	}

	@Override
	public boolean isDistinct() {
		return distinct;
	}

	@Override
	public Select setDistinct(boolean distinct) {
		this.distinct = distinct;
		return this;
	}

	@Override
	public String toSql() {
		StringBuffer slt = new StringBuffer("SELECT ");
		if (distinct) {
			slt.append("DISTINCT ");
		}
		int size = this.size();
		if (size == 0) {
			slt.append("*");
		} else {
			slt.append(queryFields.get(0).toSql());
			for (int i = 1; i < size; i++) {
				slt.append(",").append(queryFields.get(i).toSql());
			}
		}
		return slt.toString();
	}

	@Override
	public List<Object> getPlacedParameters() {
		List<Object> ppl = new ArrayList<Object>();
		if (size() > 0) {
			for (Field fld : queryFields) {
				ppl.addAll(fld.getPlacedParameters());
			}
		}
		return ppl;
	}

	@Override
	public Map<String, Object> getNamedParameters() {
		Map<String, Object> npm = new HashMap<String, Object>();
		if (size() > 0) {
			for (Field fld : queryFields) {
				npm.putAll(fld.getNamedParameters());
			}
		}
		return npm;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null || !(obj instanceof SimpleSelect)) {
			return false;
		}
		SimpleSelect other = (SimpleSelect) obj;
		if (distinct == other.isDistinct() && size() == other.size()) {
			for (Field fld : other.getQueryFields()) {
				if (!queryFields.contains(fld)) {
					return false;
				}
			}
			return true;
		}
		return false;
	}

	@Override
	public int hashCode() {
		int hc = 37 * 17 + (distinct ? 1 : 0);
		if (size() > 0) {
			for (Field fld : queryFields) {
				hc = 37 * hc + fld.hashCode();
			}
		}
		return hc;
	}

	@Override
	public String toString() {
		return toSql();
	}

}
